package com.zekdot.aptgateway.fliter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.zekdot.aptgateway.util.CheckResult;
import com.zekdot.aptgateway.util.ConfigInfo;
import com.zekdot.aptgateway.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * Create by zekdot on 20-3-17.
 */
public class LoginFilter extends ZuulFilter {
    @Autowired
    private ConfigInfo configInfo;
    private static String JWT_NO_INFO = "{\"code\":1020,\"message\":\"没有鉴权信息\"}";
    private static String JWT_FAIL = "{\"code\":1021,\"message\":\"无效的token\"}";
    private static String JWT_EXPIRE = "{\"code\":1022,\"message\":\"token过期，请重新登录\"}";
    private static String JWT_WRONG_IDENT = "{\"code\":1023,\"message\":\"token与身份不符\"}";
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
//        System.out.println(request.getRequestURL().toString());
        // 白名单
        List<String> whiteList = configInfo.whiteList;
        // 白名单排除不需要登录的url
        for(String whiteUrl:whiteList){
//            System.out.println(whiteUrl);
//            System.out.println(request.getRequestURL().toString().contains(whiteUrl));
            // 如果在白名单内
            if(request.getRequestURL().toString().contains(whiteUrl)){
//                System.out.println("不需要鉴权");
                request.setAttribute("status","failed");
                // 不需要鉴权
                return null;
            }
        }

        HttpServletResponse response = ctx.getResponse();
//        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        // 从参数列表中取出token对应的值
        String token = request.getParameter("token");
        if(token == null){
//            ctx.setResponseStatusCode(401);
//            ctx.setResponseBody("没有鉴权信息");
            ctx.setSendZuulResponse(false);
            try {
                request.setAttribute("status","failed");
                response.getWriter().println(JWT_NO_INFO);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
        CheckResult checkResult = JwtUtil.validateJWT(token);

        // 如果检验通过
        if(checkResult.isSuccess()){
            // 取出加密的内容
            Claims claims = checkResult.getClaims();
            String text = claims.getSubject();
            String username = request.getParameter("userId");
            // 验证签名
            if(username == null || !username.equals(text)){
                ctx.setSendZuulResponse(false);
                try {
                    request.setAttribute("status","failed");
                    response.getWriter().println(JWT_WRONG_IDENT);
//                    System.out.println("错误身份");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            request.setAttribute("status","success");
        }else if(checkResult.getErrCode() == CheckResult.JWT_ERRCODE_FAIL){

            ctx.setSendZuulResponse(false);
            try {
                request.setAttribute("status","failed");
                response.getWriter().println(JWT_FAIL);
//                System.out.println("JWT错误");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else if(checkResult.getErrCode() == CheckResult.JWT_ERRCODE_EXPIRE){
            ctx.setSendZuulResponse(false);
            try {
                request.setAttribute("status","failed");
                response.getWriter().println(JWT_EXPIRE);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }
}
